using Unity.VisualScripting;
using UnityEngine;
using UnityGameFramework.Runtime;

namespace LS.UGFUnits
{
    /// <summary>
    /// 框架观察者，用来
    /// </summary>
    public sealed class FrameworkObserver : GameFrameworkComponent
    {
        /// <summary>
        /// 游戏框架是否可用
        /// </summary>
        public static bool GFAvailable { get; private set; } = false;

        public static BaseComponent Base { get; private set; }
        public static ConfigComponent Config { get; private set; }
        public static DataNodeComponent DataNode { get; private set; }
        public static DataTableComponent DataTable { get; private set; }
        public static DownloadComponent Download { get; private set; }
        public static EntityComponent Entity { get; private set; }
        public static EventComponent Event { get; private set; }
        public static FileSystemComponent FileSystem { get; private set; }
        public static FsmComponent Fsm { get; private set; }
        public static LocalizationComponent Localization { get; private set; }
        public static NetworkComponent Network { get; private set; }
        public static ObjectPoolComponent ObjectPool { get; private set; }
        public static ProcedureComponent Procedure { get; private set; }
        public static ReferencePoolComponent ReferencePool { get; private set; }
        public static ResourceComponent Resource { get; private set; }
        public static SceneComponent Scene { get; private set; }
        public static SettingComponent Setting { get; private set; }
        public static SoundComponent Sound { get; private set; }
        public static UIComponent UI { get; private set; }
        public static WebRequestComponent WebRequest { get; private set; }

        protected override void Awake()
        {
            GFAvailable = true;
            base.Awake();
#if UNITY_2023_1_OR_NEWER
            Base = FindFirstObjectByType<BaseComponent>(FindObjectsInactive.Include);
#else
            Base = FindObjectOfType<BaseComponent>(true);
#endif
            if (Base != null)
            {
                Config = Base.GetComponentInChildren<ConfigComponent>();
                DataNode = Base.GetComponentInChildren<DataNodeComponent>();
                DataTable = Base.GetComponentInChildren<DataTableComponent>();
                Download = Base.GetComponentInChildren<DownloadComponent>();
                Entity = Base.GetComponentInChildren<EntityComponent>();
                Event = Base.GetComponentInChildren<EventComponent>();
                FileSystem = Base.GetComponentInChildren<FileSystemComponent>();
                Fsm = Base.GetComponentInChildren<FsmComponent>();
                Localization = Base.GetComponentInChildren<LocalizationComponent>();
                Network = Base.GetComponentInChildren<NetworkComponent>();
                ObjectPool = Base.GetComponentInChildren<ObjectPoolComponent>();
                Procedure = Base.GetComponentInChildren<ProcedureComponent>();
                ReferencePool = Base.GetComponentInChildren<ReferencePoolComponent>();
                Resource = Base.GetComponentInChildren<ResourceComponent>();
                Scene = Base.GetComponentInChildren<SceneComponent>();
                Setting = Base.GetComponentInChildren<SettingComponent>();
                Sound = Base.GetComponentInChildren<SoundComponent>();
                UI = Base.GetComponentInChildren<UIComponent>();
                WebRequest = Base.GetComponentInChildren<WebRequestComponent>();
            }
        }

        private void OnEnable()
        {
            GFAvailable = true;
        }

        private void OnDisable()
        {
            GFAvailable = false;
        }

        private void OnDestroy()
        {
            Base = null;
            Config = null;
            DataNode = null;
            DataTable = null;
            Download = null;
            Entity = null;
            Event = null;
            FileSystem = null;
            Fsm = null;
            Localization = null;
            Network = null;
            ObjectPool = null;
            Procedure = null;
            ReferencePool = null;
            Resource = null;
            Scene = null;
            Setting = null;
            Sound = null;
            UI = null;
            WebRequest = null;
            GFAvailable = false;
        }

        /// <summary>
        /// 观察框架状态，判断框架是否可用，建议每次获取框架组件或者调用框架功能时执行一次进行判断。
        /// </summary>
        /// <returns>是否在观察中</returns>
        public static bool Observing()
        {
            if (!Application.isPlaying)
                return false;

            if (GFAvailable)
                return true;

            var baseCom = GameEntry.GetComponent<BaseComponent>();
            var fo = GameEntry.GetComponent<FrameworkObserver>();
            if (!baseCom)
            {
                return false;
            }
            
            if (fo)
            {
                fo.enabled = true;
                return GFAvailable;
            }
            else
            {
                fo = FindFirstObjectByType<FrameworkObserver>(FindObjectsInactive.Include);
                if (!fo)
                {
                    fo = baseCom.AddComponent<FrameworkObserver>();
                }
                return GFAvailable;
            }
        }
    }
}